﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bots.Gatherbuddy;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Profiles;
using Styx.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Styx.Plugins;	

namespace rndbuddy
{
    static class movement_controller
    {
        public static DateTime no_unmount_until = System.DateTime.Now;
        public static int num_stucks = 0;
        public static DateTime last_stuck = System.DateTime.Now.Subtract(new TimeSpan(1, 0, 0));

        public static void check_mounting()
        {
            WoWGameObject[] gatherNodes = ObjectManager.GetObjectsOfType<WoWGameObject>().Where(o => o.IsHerb || o.IsMineral).ToArray(); // Both
            for (int i = 0; i < gatherNodes.Length; i++)
            {
                ShapeshiftForm shapeshift = StyxWoW.Me.Shapeshift;
                WoWGameObject node = gatherNodes[i];

                if (StyxWoW.Me.IsFlying && 
                    node.Distance <= settings.unmount_node_distance && 
                    node.Z - StyxWoW.Me.Z < 5 &&
                    StyxWoW.Me.Z > node.Z
                   )
                {
                    if ((TreeRoot.Current.Name.Contains("Gather") || TreeRoot.Current.Name.Contains("Profession")))
                    {
						//stop
						//Navigator.PlayerMover.MoveStop();
                        
                        //dont unmount if there was a unmount recently
                        if (System.DateTime.Now <= no_unmount_until)
                            return;

                        no_unmount_until = System.DateTime.Now.AddSeconds(settings.unmount_grace_period); //add grace

						//unmount
                        if (StyxWoW.Me.Class == WoWClass.Druid &&
                            (shapeshift == ShapeshiftForm.FlightForm || shapeshift == ShapeshiftForm.EpicFlightForm)
                           )
                        {
                            rndbuddy.log("Canceling Shapeshift");
                            Lua.DoString("RunMacroText('/cancelform')");
                            return;
                        }

                        //not druid
                        rndbuddy.log("Dismounting");
                        Lua.DoString("Dismount()");
                        return;
                    }
                }
            }
        }

        public static void jump()
        {
            if (!settings.jump)
                return;
            if (StyxWoW.Me.IsFlying)
                return;
            if (StyxWoW.Me.IsActuallyInCombat)
                return;
            if (!movement_controller.do_jump())
                return;
            Styx.Helpers.KeyboardManager.KeyUpDown((char)System.Windows.Forms.Keys.Space);

            char key2;
            //random direction
            switch (new Random().Next(0, 3))
            {
                case 0: key2 = (char)System.Windows.Forms.Keys.W; break;
                case 1: key2 = (char)System.Windows.Forms.Keys.S; break;
                case 2: key2 = (char)System.Windows.Forms.Keys.A; break;
                case 3: key2 = (char)System.Windows.Forms.Keys.D; break;
                default: key2 = (char)System.Windows.Forms.Keys.Space; break;
            }
            Styx.Helpers.KeyboardManager.KeyUpDown(key2);
        }

        public static void unstuck_attempt()
        {
            if (!StyxWoW.Me.IsFlying)
            {
                move_to_unstuck();
                return;
            }
            rndbuddy.log("Flying up to unstuck");
            WoWMovement.Move(WoWMovement.MovementDirection.JumpAscend, new TimeSpan(0, 0, 10));
        }

        public static void move_to_unstuck()
        {
            rndbuddy.log("Moving to unstuck");
            WoWMovement.MoveStop();
            WoWMovement.Move(WoWMovement.MovementDirection.StrafeLeft, new TimeSpan(0, 0, 3));
            WoWMovement.Move(WoWMovement.MovementDirection.Backwards, new TimeSpan(0, 0, 4));
        }

        public static bool do_jump()
        {
            return true; //todo: add more randomness (eg. 1 in 3...)
        }

        public static void check_stuck()
        {
            last_stuck = System.DateTime.Now;
            if ((DateTime.Now - last_stuck) > new TimeSpan(0,0,5))
            {
                num_stucks = 0;
                return;
            }

            ++num_stucks;
            rndbuddy.log("Stuck " + num_stucks.ToString() + "/" + settings.max_stucks.ToString());
            
            if (num_stucks > settings.max_stucks)
            {
                if (BotController.is_gather_botbase())
                    server_pipe.report_stuck(StyxWoW.Me.X, StyxWoW.Me.Y, StyxWoW.Me.Z);
                unstuck_attempt();
                num_stucks = 0;
            }

            return;
        }

    }
}
